package com.yunao.service.report.esou;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class DbUtil2 {

	/**
	 * 查询用户私有专题和组织所有共享专题
	 */
	public static final String QUERY_SUBJECT_PERSONAL = "FROM aloneReport WHERE (user = ? ) ";

	private static DbUtil2 instance = null;

	private DbUtil2() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		sessionFactory = (SessionFactory) ctx.getBean("sessionFactory");
	}

	public static DbUtil2 getInstance() {
		if (instance == null)
			instance = new DbUtil2();
		return instance;
	}

	private SessionFactory sessionFactory;

	public Session getSession() {
		return sessionFactory.openSession();
	}

	public void save(Object obj) {
		Session session = null;
		try {
			session = sessionFactory.openSession();
			session.beginTransaction();
			session.save(obj);
			session.getTransaction().commit();
		} finally {
			if (session != null)
				session.close();
		}
	}

	public void saveAll(Collection<?> c) {
		Session session = null;
		try {
			Iterator<?> it = c.iterator();
			int i = 0;
			session = sessionFactory.openSession();
			session.beginTransaction();
			while (it.hasNext()) {
				Object obj = it.next();
				session.save(obj);
				if (i % 20 == 0) {
					session.flush();
					session.clear();
				}
				i++;
			}
			session.getTransaction().commit();
		} finally {
			if (session != null)
				session.close();
		}
	}

	public void delete(Object obj) {
		Session session = null;
		try {
			session = sessionFactory.openSession();
			session.beginTransaction();
			session.delete(obj);
			session.getTransaction().commit();
		} finally {
			if (session != null)
				session.close();
		}
	}

	public void deleteAll(Collection<?> c) {
		Session session = null;
		try {
			Iterator<?> it = c.iterator();
			int i = 0;
			session = sessionFactory.openSession();
			Transaction transaction = session.beginTransaction();
			while (it.hasNext()) {
				Object obj = it.next();
				session.delete(obj);
				if (i % 20 == 0) {
					session.flush();
					session.clear();
				}
				i++;
			}
			transaction.commit();
		} finally {
			if (session != null)
				session.close();
		}
	}

	public void update(Object obj) {
		Session session = null;
		try {
			session = sessionFactory.openSession();
			session.beginTransaction();
			session.update(obj);
			session.getTransaction().commit();
		} finally {
			if (session != null)
				session.close();
		}
	}

	public void updateAll(Collection<?> c) {
		Session session = null;
		try {
			Iterator<?> it = c.iterator();
			int i = 0;
			session = sessionFactory.openSession();
			session.beginTransaction();
			while (it.hasNext()) {
				Object obj = it.next();
				session.update(obj);
				if (i % 20 == 0) {
					session.flush();
					session.clear();
				}
				i++;
			}
			session.getTransaction().commit();
		} finally {
			if (session != null)
				session.close();
		}
	}

	public int count(String hql, Object... params) {
		Session session = null;
		try {
			session = sessionFactory.openSession();
			Query query = session.createQuery(hql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					if (params[i] == null)
						continue;
					query.setParameter(i, params[i]);
				}
			}
			Object obj = query.uniqueResult();
			if (obj == null)
				return 0;
			return (int) ((Long) obj).intValue();
		} finally {
			if (session != null)
				session.close();
		}
	}

	public Object get(Class<?> clazz, Serializable id) {
		Session session = null;
		try {
			session = sessionFactory.openSession();
			return session.get(clazz, id);
		} finally {
			if (session != null)
				session.close();
		}
	}

	public Object load(Class<?> clazz, Serializable id) {
		Session session = null;
		try {
			session = sessionFactory.openSession();
			return session.load(clazz, id);
		} finally {
			if (session != null)
				session.close();
		}
	}

	public Object uniqueResult(String hql, Object... params) {
		Session session = null;
		try {
			session = sessionFactory.openSession();
			Query query = session.createQuery(hql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					if (params[i] == null)
						continue;
					query.setParameter(i, params[i]);
				}
			}
			Object obj = query.uniqueResult();
			return obj;
		} finally {
			if (session != null)
				session.close();
		}
	}

	public List<?> query(String hql, Object... params) {
		Session session = null;
		try {
			session = sessionFactory.openSession();
			Query query = session.createQuery(hql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					if (params[i] == null)
						continue;
					query.setParameter(i, params[i]);
				}
			}
			return query.list();
		} finally {
			if (session != null)
				session.close();
		}
	}

	public List<?> query(int page, int size, String hql, Object... params) {
		Session session = null;
		try {
			session = sessionFactory.openSession();
			Query query = session.createQuery(hql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					if (params[i] == null)
						continue;
					query.setParameter(i, params[i]);
				}
			}
			query.setFirstResult(((page < 1 ? 1 : page) - 1) * size);
			query.setMaxResults(size);
			return query.list();
		} finally {
			if (session != null)
				session.close();
		}
	}

	public Iterator<?> iterate(String hql, Object... params) {
		Session session = null;
		try {
			session = sessionFactory.openSession();
			Query query = session.createQuery(hql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					if (params[i] == null)
						continue;
					query.setParameter(i, params[i]);
				}
			}
			List<?> list = query.list();
			Iterator<?> it = list.iterator();
			return it;
		} finally {
			if (session != null)
				session.close();
		}
	}

	public void execute(String hql, Object... params) {
		Session session = null;
		try {
			session = sessionFactory.openSession();
			session.beginTransaction();
			Query query = session.createQuery(hql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					if (params[i] == null)
						continue;
					query.setParameter(i, params[i]);
				}
			}
			query.executeUpdate();
			session.getTransaction().commit();
		} finally {
			if (session != null)
				session.close();
		}
	}

}
